/**
 * Agent API Routes
 * 
 * Handles agent query requests (streaming and single mode)
 */

import { Hono } from 'hono';
import { stream } from 'hono/streaming';
import { executeStreamingQuery, executeSingleQuery } from '@/agent/query';
import type { QueryRequest, ApiResponse } from '@/types';
import { logger } from '@/utils/logger';

export const agentRoutes = new Hono();

/**
 * POST /api/agent/query
 * 
 * Execute a query to Claude Agent SDK
 * Supports both streaming and single message modes
 */
agentRoutes.post('/query', async (c) => {
  try {
    const body = await c.req.json<QueryRequest>();
    const { prompt, options = {} } = body;

    // Validate request
    if (!prompt) {
      const response: ApiResponse = {
        success: false,
        error: {
          code: 'INVALID_REQUEST',
          message: 'Missing required field: prompt',
        },
        timestamp: new Date().toISOString(),
      };
      return c.json(response, 400);
    }

    // Check if streaming is requested
    const isStreaming = options.includePartialMessages !== false;

    if (isStreaming) {
      // Streaming mode - use Server-Sent Events
      return stream(c, async (stream) => {
        try {
          logger.info('Starting streaming query');

          for await (const response of executeStreamingQuery(body)) {
            // Send each response as SSE event
            await stream.write(`data: ${JSON.stringify(response)}\n\n`);
          }

          logger.info('Streaming query completed');
        } catch (error) {
          logger.error('Streaming error', error);
          await stream.write(`data: ${JSON.stringify({
            type: 'error',
            error: {
              code: 'STREAM_ERROR',
              message: error instanceof Error ? error.message : 'Unknown error',
            },
          })}\n\n`);
        }
      });
    } else {
      // Single message mode - return JSON response
      logger.info('Starting single query');
      const result = await executeSingleQuery(body);

      const response: ApiResponse = {
        success: result.type !== 'error',
        data: result,
        timestamp: new Date().toISOString(),
      };

      return c.json(response);
    }
  } catch (error) {
    logger.error('Query request failed', error);

    const response: ApiResponse = {
      success: false,
      error: {
        code: 'REQUEST_ERROR',
        message: error instanceof Error ? error.message : 'Unknown error',
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 500);
  }
});

/**
 * POST /api/agent/query/streaming
 * 
 * Execute a streaming query (explicit streaming endpoint)
 */
agentRoutes.post('/query/streaming', async (c) => {
  try {
    const body = await c.req.json<QueryRequest>();
    const { prompt } = body;

    if (!prompt) {
      const response: ApiResponse = {
        success: false,
        error: {
          code: 'INVALID_REQUEST',
          message: 'Missing required field: prompt',
        },
        timestamp: new Date().toISOString(),
      };
      return c.json(response, 400);
    }

    // Force streaming mode
    body.options = {
      ...body.options,
      includePartialMessages: true,
    };

    return stream(c, async (stream) => {
      try {
        for await (const response of executeStreamingQuery(body)) {
          await stream.write(`data: ${JSON.stringify(response)}\n\n`);
        }
      } catch (error) {
        logger.error('Streaming error', error);
        await stream.write(`data: ${JSON.stringify({
          type: 'error',
          error: {
            code: 'STREAM_ERROR',
            message: error instanceof Error ? error.message : 'Unknown error',
          },
        })}\n\n`);
      }
    });
  } catch (error) {
    logger.error('Streaming query request failed', error);

    const response: ApiResponse = {
      success: false,
      error: {
        code: 'REQUEST_ERROR',
        message: error instanceof Error ? error.message : 'Unknown error',
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 500);
  }
});

/**
 * POST /api/agent/query/single
 * 
 * Execute a single message query (explicit single mode endpoint)
 */
agentRoutes.post('/query/single', async (c) => {
  try {
    const body = await c.req.json<QueryRequest>();
    const { prompt } = body;

    if (!prompt) {
      const response: ApiResponse = {
        success: false,
        error: {
          code: 'INVALID_REQUEST',
          message: 'Missing required field: prompt',
        },
        timestamp: new Date().toISOString(),
      };
      return c.json(response, 400);
    }

    // Force single mode
    body.options = {
      ...body.options,
      includePartialMessages: false,
    };

    const result = await executeSingleQuery(body);

    const response: ApiResponse = {
      success: result.type !== 'error',
      data: result,
      timestamp: new Date().toISOString(),
    };

    return c.json(response);
  } catch (error) {
    logger.error('Single query request failed', error);

    const response: ApiResponse = {
      success: false,
      error: {
        code: 'REQUEST_ERROR',
        message: error instanceof Error ? error.message : 'Unknown error',
      },
      timestamp: new Date().toISOString(),
    };

    return c.json(response, 500);
  }
});

